import logger from '../services/logger.js'

/**
 * 文本分段工具
 */
export class TextChunker {
  /**
   * 将文本分割成块
   * @param {string} text - 要分割的文本
   * @param {object} options - 分割选项
   * @param {number} options.chunkSize - 每个块的最大大小
   * @param {number} options.overlap - 块之间的重叠大小
   * @param {string} options.separator - 分隔符，默认为段落分隔符
   * @returns {Array<{content: string, length: number}>} 分割后的文本块数组
   */
  static splitText(text, { chunkSize, overlap, separator = '\n\n' }) {
    try {      
      const chunks = []
      
      // 如果指定了自定义分隔符，使用分隔符分割
      if (separator !== '\n\n') {
        return this.splitByCustomSeparator(text, { chunkSize, overlap, separator });
      }
      
      // 首先按语义单元分割（章节、段落等）
      const sections = this.splitIntoSections(text)
      let currentChunk = ''
      
      for (const section of sections) {
        // 如果单个章节超过块大小，需要进一步分割
        if (section.length > chunkSize) {
          // 先添加当前块
          if (currentChunk) {
            chunks.push({
              content: currentChunk.trim(),
              length: currentChunk.length
            })
            currentChunk = ''
          }
          
          // 按段落分割章节
          const paragraphs = section.split(/\n\s*\n/)
          for (const paragraph of paragraphs) {
            if (paragraph.length > chunkSize) {
              // 如果段落太长，按句子分割
              const sentenceChunks = this.splitParagraphIntoChunks(paragraph, { chunkSize, overlap })
              chunks.push(...sentenceChunks)
            } else {
              if (currentChunk && (currentChunk.length + paragraph.length + 2) > chunkSize) {
                chunks.push({
                  content: currentChunk.trim(),
                  length: currentChunk.length
                })
                currentChunk = paragraph
              } else {
                currentChunk += (currentChunk ? '\n\n' : '') + paragraph
              }
            }
          }
          continue
        }
        
        // 如果添加章节后超过块大小，先保存当前块
        if (currentChunk && (currentChunk.length + section.length + 2) > chunkSize) {
          chunks.push({
            content: currentChunk.trim(),
            length: currentChunk.length
          })
          currentChunk = section
        } else {
          currentChunk += (currentChunk ? '\n\n' : '') + section
        }
      }
      
      // 添加最后一个块
      if (currentChunk) {
        chunks.push({
          content: currentChunk.trim(),
          length: currentChunk.length
        })
      }
      
      // 处理块之间的重叠
      if (overlap > 0) {
        return this.addOverlap(chunks, overlap)
      }
      
      return chunks
    } catch (error) {
      logger.error('Text chunking failed:', error)
      throw error
    }
  }
  
  /**
   * 将文本分割成语义章节
   * @private
   */
  static splitIntoSections(text) {
    // 识别常见的章节标记
    const sectionMarkers = [
      /^第[一二三四五六七八九十百千]+[章节篇]/m,  // 中文章节
      /^Chapter\s+\d+/mi,  // 英文章节
      /^[\d.]+\s+[A-Z]/m,  // 编号标题
      /^[一二三四五六七八九十][、.]\s+/m,  // 中文编号
      /^[#]{1,6}\s+/m,  // Markdown 标题
      /^.*?\n[=-]{3,}/m,  // Markdown 下划线标题
    ]
    
    // 按可能的章节标记分割
    let sections = [text]
    for (const marker of sectionMarkers) {
      sections = sections.flatMap(section => 
        section.split(new RegExp(`(?=${marker.source})`, 'gm'))
      )
    }
    
    return sections.map(s => s.trim()).filter(Boolean)
  }
  
  /**
   * 处理块之间的重叠
   * @private
   */
  static addOverlap(chunks, overlap) {
    if (chunks.length <= 1) return chunks
    
    const result = []
    for (let i = 0; i < chunks.length; i++) {
      const chunk = chunks[i]
      
      if (i > 0) {
        // 从上一个块的末尾获取重叠内容
        const prevChunk = result[i - 1]
        const sentences = prevChunk.content.split(/(?<=[.!?。！？])\s+/)
        let overlapText = ''
        
        // 从后往前添加句子，直到达到重叠大小
        for (let j = sentences.length - 1; j >= 0; j--) {
          const sentence = sentences[j]
          if (overlapText.length + sentence.length > overlap) break
          overlapText = sentence + ' ' + overlapText
        }
        
        // 添加重叠内容到当前块的开头
        if (overlapText) {
          chunk.content = overlapText.trim() + '\n\n' + chunk.content
          chunk.length = chunk.content.length
        }
      }
      
      result.push(chunk)
    }
    
    return result
  }
  
  /**
   * 使用自定义分隔符分割文本
   * @param {string} text - 要分割的文本
   * @param {object} options - 分割选项
   * @returns {Array<{content: string, length: number}>} 分割后的文本块数组
   */
  static splitByCustomSeparator(text, { chunkSize, overlap, separator }) {
    // 首先按分隔符分割文本
    const rawChunks = text.split(separator)
    const chunks = []
    let currentChunk = ''

    for (const chunk of rawChunks) {
      // 如果当前块加上新内容不超过限制，则添加
      if (currentChunk.length + chunk.length < chunkSize) {
        currentChunk += (currentChunk ? separator : '') + chunk
      } else {
        // 否则保存当前块并开始新块
        if (currentChunk) {
          chunks.push({
            content: currentChunk.trim(),
            length: currentChunk.length
          })
          
          // 保留一部分重叠内容
          if (overlap > 0) {
            const words = currentChunk.split(' ')
            currentChunk = words
              .slice(Math.max(0, words.length - Math.ceil(overlap / 5))) // 估算重叠单词数
              .join(' ')
          } else {
            currentChunk = ''
          }
        }
        currentChunk += (currentChunk ? separator : '') + chunk
      }
    }

    // 添加最后一个块
    if (currentChunk) {
      chunks.push({
        content: currentChunk.trim(),
        length: currentChunk.length
      })
    }

    return chunks
  }
  
  /**
   * 将段落分割成更小的块
   * @private
   */
  static splitParagraphIntoChunks(paragraph, { chunkSize, overlap }) {
    const chunks = []
    
    // 尝试按句子分割
    const sentences = paragraph.split(/(?<=[.!?])\s+/)
    
    let currentChunk = ''
    for (let i = 0; i < sentences.length; i++) {
      const sentence = sentences[i].trim()
      if (!sentence) continue
      
      // 如果单个句子超过块大小，按单词分割
      if (sentence.length > chunkSize) {
        if (currentChunk) {
          chunks.push({
            content: currentChunk.trim(),
            length: currentChunk.length
          })
          currentChunk = ''
        }
        
        // 按单词分割句子
        const words = sentence.split(/\s+/)
        let wordChunk = ''
        
        for (let j = 0; j < words.length; j++) {
          const word = words[j]
          
          if (wordChunk && (wordChunk.length + word.length + 1) > chunkSize) {
            chunks.push({
              content: wordChunk.trim(),
              length: wordChunk.length
            })
            wordChunk = ''
          }
          
          wordChunk += (wordChunk ? ' ' : '') + word
        }
        
        if (wordChunk) {
          chunks.push({
            content: wordChunk.trim(),
            length: wordChunk.length
          })
        }
        
        continue
      }
      
      // 如果添加句子后超过块大小，先保存当前块
      if (currentChunk && (currentChunk.length + sentence.length + 1) > chunkSize) {
        chunks.push({
          content: currentChunk.trim(),
          length: currentChunk.length
        })
        
        // 如果需要重叠，保留最后一个句子
        if (overlap > 0 && i > 0) {
          const lastSentence = sentences[i - 1]
          if (lastSentence.length < overlap) {
            currentChunk = lastSentence
          } else {
            currentChunk = ''
          }
        } else {
          currentChunk = ''
        }
      }
      
      // 添加句子到当前块
      if (currentChunk) {
        currentChunk += ' ' + sentence
      } else {
        currentChunk = sentence
      }
    }
    
    // 添加最后一个块
    if (currentChunk) {
      chunks.push({
        content: currentChunk.trim(),
        length: currentChunk.length
      })
    }
    
    return chunks
  }
  
} 